package javaSenior.threadExer;

/**
 * @author Lenl
 * @version v1.0
 * @create 2021-06-03 1:08
 * @description 线程通信的应用：生产者消费者问题
 *
 *分析：生产者线程、消费者线程
 *共享数据：店员（或产品）
 * 解决线程安全问题：三种方法
 * 线程通信
 *
 *
 */
public class ProductTest {
    public static void main(String[] args) {
        Clerk clerk=new Clerk();

        Producer p1=new Producer(clerk);
        Consumer c1=new Consumer(clerk);
        p1.setName("生产者");
        c1.setName("消费者");
        p1.start();
        c1.start();

    }
}

class Clerk{
    private int productCount=0;

    //生产产品
    public synchronized void produceProduct() {
        if(productCount<20){
            System.out.println(Thread.currentThread().getName()+"：开始生产第"+(++productCount)+"个产品");
            notify();
        }else {

            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //消费产品
    public synchronized void consumeProduct()  {
        if(productCount>0){
            System.out.println(Thread.currentThread().getName()+"：开始生产第"+(productCount--)+"个产品");
            notify();
        }else {
            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Producer extends Thread{
    private Clerk clerk;

    public Producer(Clerk clerk){
        this.clerk=clerk;
    }

    @Override
    public void run() {
        System.out.println(getName()+"：开始生产产品...");
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.produceProduct();
        }
    }
}
class Consumer extends Thread{
    private Clerk clerk;

    public Consumer(Clerk clerk){
        this.clerk=clerk;
    }

    @Override
    public void run() {
        System.out.println(getName()+"：消费了产品...");
        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            clerk.consumeProduct();
        }
    }
}

